﻿using System;
using System.Drawing;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Microsoft.WindowsCE.Forms;
using System.Windows.Forms;

namespace GogTasks.UserControls
{
    class Util
    {
        public const string NonAlphaNumCharsRegex = "[ \\.,:;\\-\\(\\)!\\*]";

        /// <summary>
        /// Splits a text string in lines depending on font and maxWidth
        /// </summary>
        /// <returns></returns>
        public static List<String> SplitInLines(string text, Graphics g, Font font, int maxWidth, out int lineHeight)
        {
            lineHeight = 0;
            // 1. find size
            string[] words = Regex.Split(text.TrimEnd(), "(?<=" + NonAlphaNumCharsRegex + ")+", RegexOptions.ExplicitCapture);
            //string[] words = text.Split(' ');


            int width = 0;
            int lineCount = 1;
            var lines = new List<String>();
            string line = String.Empty;
            for (int i = 0; i < words.Length; i++)
            {
                var word = words[i];
                var size = g.MeasureString(word, font);
                int wordWidth = (int)size.Width;
                bool overflow = width == 0 && wordWidth > maxWidth; // Single word exceeding line length?
                width += (int)size.Width;
                if ((int) size.Height > 0) lineHeight = (int)size.Height;
                if (!overflow && width > maxWidth)
                {
                    // Next line
                    i--;
                    lineCount++;
                    lines.Add(line);
                    line = String.Empty;
                    width = 0;
                }
                else
                {
                    line += word;
                }
            }
            if (line != String.Empty) lines.Add(line);
            return lines;
        }
        
        /// <summary>
        /// Adds event handlers to the input panel so that the control behind it
        /// won't be hidden when enabled. 
        /// </summary>
        /// <param name="keyboard">Input panel object</param>
        /// <param name="parentPanel">Parenting panel that can be moved to show the control</param>
        /// <param name="control">Control that is hidden by the keyboard</param>
        public static void FixControlHiddenByInputPanel(InputPanel keyboard, Panel parentPanel, Control control)
        {
            new KeyboardFixer(keyboard, parentPanel, control);
        }
        
        class KeyboardFixer
        {
            internal KeyboardFixer(InputPanel keyboard, Panel parentControl, Control control)
            {
                keyboard.EnabledChanged += InputPanel_EnabledChanged;
                _control = control;
                _keyboard = keyboard;
                _parentPanel = parentControl;
                _control.GotFocus += InputPanel_EnabledChanged;
                _control.LostFocus += InputPanel_EnabledChanged;
            }

            private InputPanel _keyboard;
            private Panel _parentPanel;
            private Control _control;
            
            public  void InputPanel_EnabledChanged(object sender, EventArgs args)
            {
                var keyboard = _keyboard;
                var parentPanel = _parentPanel;
                var control = _control;
                bool isMoved = parentPanel.Location.Y < 0;
                if (keyboard.Enabled && control.Focused )
                {
                    if (!isMoved)
                    {
                        const int margin = 5; // Some margin down to the input panel
                        var visibleDesktop = keyboard.VisibleDesktop;
                        var loc = parentPanel.Location;
                        // Find the # of pixels to pan the control panel up
                        var _scrolledUp = control.Bottom - visibleDesktop.Bottom + visibleDesktop.Top + margin;
                        parentPanel.Location = new Point(loc.X, loc.Y - _scrolledUp);
                    }
                }
                else
                {
                    parentPanel.Location = new Point(parentPanel.Location.X, 0);
                }
            }
        }
    }
}
